package com.learning.server.redis.bit;

import redis.clients.jedis.Jedis;

import java.time.LocalDate;

public class RedisBit {

    private static final int BIT_AMOUNT_IN_ONE_BYTE =8;

    private static final String host="127.0.0.1";

    private static final int port=6379;

    public static final Jedis jedis=new Jedis(host,port);

    private static final String userId = "user_1";


    public int bitCountByBitIndex(String key, long startBitIndex, long endBitIndex){
        int startByteIndex = getByteIndexInTheBytes(startBitIndex);
        int endByteIndex = getByteIndexInTheBytes(endBitIndex);
        byte[] bytes = jedis.getrange(key.getBytes(), startByteIndex, endByteIndex);
        int totalBitInBytes = getTotalBitInBytes(bytes);
        int startBitIndexInFirstByte = getBitIndexInTheByte(startBitIndex);
        int endBitIndexInLastByte = getBitIndexInTheByte(endBitIndex);
        byte firstByte = bytes[0];
        byte lastByte = bytes[bytes.length-1];
        for(int i=7;i>(BIT_AMOUNT_IN_ONE_BYTE-1-startBitIndexInFirstByte);i--){
            if(((firstByte>>i)&1)==1){
                totalBitInBytes--;
            }
        }
        for(int i=0;i<(BIT_AMOUNT_IN_ONE_BYTE-1-endBitIndexInLastByte);i++){
            if(((lastByte>>i)&1)==1){
                totalBitInBytes--;
            }
        }

        return totalBitInBytes;
    }

    private int getTotalBitInBytes(byte[] bytes){
        int count=0;
        for(byte b:bytes){
            for(int i = 0; i< BIT_AMOUNT_IN_ONE_BYTE; i++){
                if(((b>>i)&1)==1){
                    count++;
                }
            }
        }
        return count;
    }

    private int getByteIndexInTheBytes(long offset){
        return (int) offset/ BIT_AMOUNT_IN_ONE_BYTE;
    }

    private int getBitIndexInTheByte(long offset){
        return (int)(offset-offset/ BIT_AMOUNT_IN_ONE_BYTE * BIT_AMOUNT_IN_ONE_BYTE);
    }


    public void loadData(){

        jedis.setbit(userId,0,true);
        jedis.setbit(userId,1,true);
        jedis.setbit(userId,2,false);
        jedis.setbit(userId,3,true);
        jedis.setbit(userId,4,false);
        jedis.setbit(userId,5,true);
        jedis.setbit(userId,6,false);
        jedis.setbit(userId,7,true);
        jedis.setbit(userId,8,false);
        jedis.setbit(userId,9,true);

    }
    public static void main(String[] args){

        RedisBit redisBit = new RedisBit();
        redisBit.loadData();

        int count = redisBit.bitCountByBitIndex(userId,0,9);

        System.out.println("count " + count);

    }

}
